#include "StdAfx.h"
#include "DiscoMachine.h"

CDiscoMachine::CDiscoMachine()
{
}

CDiscoMachine::~CDiscoMachine()
{
}

int CDiscoMachine::Init()
{
CBurgerTimeMachine::Init();
MainCPU->SetUser(this);
SoundCPU->SetUser(this);
MainCPU->SetRead(ReadMainCPU);
MainCPU->SetWrite(WriteMainCPU);
MainCPU->SetOp(OpMainCPU);
SoundCPU->SetRead(ReadSoundCPU);
SoundCPU->SetWrite(WriteSoundCPU);
SoundCPU->SetOp(ReadSoundCPU);
return(0);
}

void CDiscoMachine::Poll()
{
/*u32 n;

Input->Poll();
n = Input->Get();
Input1 = Input2 = Input3 = 0;
if(n & I_UP)		Input1 |= 4;
if(n & I_DOWN)		Input1 |= 8;
if(n & I_LEFT)		Input1 |= 2;
if(n & I_RIGHT)	Input1 |= 1;
if(n & I_B1)		Input1 |= 0x10;
if(n & I_START1)	Input1 |= 0x80;
if(n & I_START2)	Input2 |= 0x80;
if(n & I_COIN1)	Input3 |= 0x40;
if(n & I_COIN2)	Input3 |= 0x80;
if(Input3 & 0xC0)
	MainCPU->NMI();
n = Input->GetDip();
Dip1 = (u8)n & 0x7F;
Dip2 = (u8)(n >> 8);*/
}

void CDiscoMachine::RenderScreen(u8 *dest,int pitch)
{
memset(dest,0,256*pitch);
RenderChars(dest,pitch,0,(VideoControl2 & 0xC) << 1);
RenderSprites(dest,pitch);
}

void CDiscoMachine::RenderSprites(u8 *dest,int pitch)
{
int offs,i,x,y;
u8 *b[3];
u8 *V = SpriteRAM;

b[0] = CHRROM + 0x0000;
b[1] = CHRROM + 0x2000;
b[2] = CHRROM + 0x4000;
for(i=0,offs=0;i<8;i++,offs+=4) //draw 8 sprites
	{
	int flip;

	if((V[offs] & 1) == 0)
		continue;
	x = 240 - V[offs + 3];
	y = 240 - V[offs + 2];
	flip = V[offs] & 6;
	if(VideoControl & 1)
		{
		x = 240 - x;
		y = 240 - y;
		flip = ~flip;
		}
	y -= 1;
	switch(flip & 6)
		{
		case 0:drawtile_16x16(dest,pitch,V[offs + 1],(u8)x,(u8)y,b);break;
		case 2:drawtile_16x16_flipy(dest,pitch,V[offs + 1],(u8)x,(u8)y,b);break;
		case 4:drawtile_16x16_flipx(dest,pitch,V[offs + 1],(u8)x,(u8)y,b);break;
		case 6:drawtile_16x16_flipxy(dest,pitch,V[offs + 1],(u8)x,(u8)y,b);break;
		}
	}
}

u8 CDiscoMachine::OpMainCPU(void *user,u32 addr)
{
CDiscoMachine *M = (CDiscoMachine*)user;

return(M->NewROM[addr]);
}

u8 CDiscoMachine::ReadMainCPU(void *user,u32 addr)
{
CDiscoMachine *M = (CDiscoMachine*)user;

switch(addr & 0xF000)
	{
	case 0x0000:
		if(addr < 0x500)
			return(M->MainRAM[addr]);
		break;
	case 0x2000:
	case 0x3000:
	case 0x4000:
	case 0x5000:
	case 0x6000:
	case 0x7000:
		return(M->CHRROM[addr - 0x2000]);
	case 0x8000:
		if(addr < 0x8400)
			return(M->VideoRAM[addr & 0x3FF]);
		else if(addr < 0x8800)
			return(M->ColorRAM[addr & 0x3FF]);
		else if(addr < 0x8820)
			return(M->SpriteRAM[addr & 0x1F]);
		break;
	case 0x9000:
		switch(addr)
			{
			case 0x9000:	return(M->InputData[2]);
			case 0x9200:	return(M->InputData[0]);
			case 0x9400:	return(M->InputData[1]);
			case 0x9800:	return(M->Dip[0]);
			case 0x9A00:	return(M->Dip[1]);
			case 0x9C00:	return(M->VBlank);
			}
		break;
	case 0xA000:
	case 0xB000:
	case 0xC000:
	case 0xD000:
	case 0xE000:
	case 0xF000:
		return(M->MainROM[addr]);
	}
message("unhandled read (main cpu, addr $%04X)\n",addr);
return(0);
}

void CDiscoMachine::WriteMainCPU(void *user,u32 addr,u8 data)
{
CDiscoMachine *M = (CDiscoMachine*)user;

switch(addr & 0xF000)
	{
	case 0x0000:
		if(addr < 0x500)
			M->MainRAM[addr] = data;
		break;
	case 0x2000:
	case 0x3000:
	case 0x4000:
	case 0x5000:
	case 0x6000:
	case 0x7000:
		M->BGROM[addr - 0x2000] = data;
		break;
	case 0x8000:
		if(addr < 0x8400)
			M->VideoRAM[addr & 0x3FF] = data;
		else if(addr < 0x8800)
			M->ColorRAM[addr & 0x3FF] = data;
		else if(addr < 0x8820)
			M->SpriteRAM[addr & 0x1F] = data;
		break;
	case 0x9000:
		switch(addr)
			{
			case 0x9A00:	M->WriteSoundControl(data);	break;
			case 0x9C00:	M->VideoControl2 = data;		break;
			default:
				message("unhandled write (main cpu, addr $%04X = $%02X)\n",addr,data);
				break;
			}
		break;
	default:
		message("unhandled write (main cpu, addr $%04X = $%02X)\n",addr,data);
		break;
	}
M->btimeDecrypt();
}

u8 CDiscoMachine::ReadSoundCPU(void *user,u32 addr)
{
CDiscoMachine *M = (CDiscoMachine*)user;

switch(addr & 0xF000)
	{
	case 0x0000:
		if(addr < 0x400)				//ram
			return(M->SoundRAM[addr]);
		break;
	case 0x8000:						//sound latch
		return(M->SoundControl);
	case 0xF000:						//rom
		return(M->SoundROM[addr]);
	}
message("unhandled read (sound cpu, addr $%04X)\n",addr);
return(0);
}

void CDiscoMachine::WriteSoundCPU(void *user,u32 addr,u8 data)
{
CDiscoMachine *M = (CDiscoMachine*)user;

switch(addr & 0xF000)
	{
	case 0x0000:
		if(addr >= 0x0400)
			message("unhandled write (sound cpu, addr $%04X = $%02X)\n",addr,data);
		else
			M->SoundRAM[addr] = data;
		break;
	case 0x4000:	AY8910Write(0,1,data);	break;
	case 0x5000:	AY8910Write(0,0,data);	break;
	case 0x6000:	AY8910Write(1,1,data);	break;
	case 0x7000:	AY8910Write(1,0,data);	break;
	case 0x8000:break;
	case 0xC000:							//irq enable
		message("irq control write = $%02X\n",data);
		break;
	default:
		message("unhandled write (sound cpu, addr $%04X = $%02X)\n",addr,data);
		break;
	}
}
